package com.medicine.controller.admin;

import com.medicine.dto.MedicineDTO;
import com.medicine.dto.MedicinePageQueryDTO;
import com.medicine.dto.MedicinePageQueryDTO;
import com.medicine.entity.Medicine;
import com.medicine.result.PageResult;
import com.medicine.result.Result;
import com.medicine.service.MedicineService;
import com.medicine.vo.MedicineVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;

/**
 * 药品管理
 */
@RestController
@RequestMapping("/admin/dish")
@Api(tags = "药品相关接口")
@Slf4j
public class MedicineController {

    @Autowired
    private MedicineService medicineService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增药品
     *
     * @param medicineDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增药品")
    public Result save(@RequestBody MedicineDTO medicineDTO) {
        log.info("新增药品：{}", medicineDTO);
        medicineService.saveWithSpecification(medicineDTO);

        //清理缓存数据：
        //注意不是一次性清除redis中的所有缓存数据，而是哪一份缓存数据受影响，那我们
        //   清理哪一份缓存数据就可以了。当前新增的这个菜品所属的分类这个key受到影响。
        String key = "medicine_" + medicineDTO.getCategoryId();
        cleanCache(key);

        return Result.success();
    }



    /**
     * 药品分页查询
     * @param medicinePageQueryDTO
     * @return
     */
    @GetMapping("/page")
    @ApiOperation("药品分页查询")
    public Result<PageResult> page(MedicinePageQueryDTO medicinePageQueryDTO) {
        log.info("药品分页查询:{}", medicinePageQueryDTO);
        PageResult pageResult = medicineService.pageQuery(medicinePageQueryDTO);
        return Result.success(pageResult);
    }

    /**
     * 药品批量删除
     *
     * @param ids
     * @return
     */
    @DeleteMapping
    @ApiOperation("药品批量删除")
    public Result delete(@RequestParam List<Long> ids) {
        log.info("药品批量删除：{}", ids);
        medicineService.deleteBatch(ids);//后绪步骤实现

        //将所有的菜品缓存数据清理掉，所有以medicine_开头的key：
        //批量删除有可能删除多个药品，而这多个药品可能属于同一个分类，也有可能是某些不同
        //  分类下面的药品，也就是说可能会影响到多个key，具体影响几个key只能查询数据库才能知道，
        //  其实不需要那么复杂，只要你批量删除之后 直接把所有的缓存数据也就是medicine_开头的缓存
        //  数据都清理掉就可以了。
        //注意：删除的时候不识别通配符，不能直接根据key删除，所以需要先把key查出来在进行删除（redisTemplate.keys(pattern)）
        //删除是支持集合collection的 即一次性把所有的key都删除，所以这个地方就没必要遍历set集合一个个的来删除了。
        cleanCache("medicine_*");

        return Result.success();
    }


    /**
     * 根据id查询药品
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据id查询药品")
    public Result<MedicineVO> getById(@PathVariable Long id) {
        log.info("根据id查询药品：{}", id);
        MedicineVO dishVO = medicineService.getByIdWithSpecification(id);
        return Result.success(dishVO);
    }

    /**
     * 修改药品
     *
     * @param medicineDTO
     * @return
     */
    @PutMapping
    @ApiOperation("修改药品")
    public Result update(@RequestBody MedicineDTO medicineDTO) {
        log.info("修改药品：{}", medicineDTO);
        medicineService.updateWithSpecification(medicineDTO);
        return Result.success();
    }

    /**
     * 根据分类id查询药品
     * @param categoryId
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据分类id查询药品")
    public Result<List<Medicine>> list(Long categoryId){
        List<Medicine> list = medicineService.list(categoryId);
        return Result.success(list);
    }

    /**
     * 药品起售停售
     * @param status
     * @param id
     * @return
     */
    @PostMapping("/status/{status}")
    @ApiOperation("药品起售停售")
    public Result<String> startOrStop(@PathVariable Integer status, Long id){
        medicineService.startOrStop(status,id);

        //将所有的药品缓存数据清理掉，所有以medicine_开头的key
        //   想要精确清理只清理某一个key：根据菜品的id把对应的药品数据查询出来，药品里面就有
        //   分类的id,之后动态的把key构造出来 然后清理某一个key就可以了。但是这样写需要
        //   额外的去查询数据 就有的得不偿失了。所以这里同样是删除所有的缓存数据。
        cleanCache("medicine_*");

        return Result.success();
    }


    /**
     * 抽取清理缓存的方法
     *  只在当前类中使用，所以私有的就可以了。
     * @param pattern
     */
    private void cleanCache(String pattern){
        Set keys = redisTemplate.keys(pattern);
        redisTemplate.delete(keys);
    }
}